using System;
using System.Text;
using System.IO;
using System.Web;
using System.Text.RegularExpressions;
using System.Web.Caching;

namespace DalatCooking.Core.Web.HttpHandlers
{
    public class ScriptHandler : IHttpHandler
    {

        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return false; }
        }

        private const string SCRIPT_CACHE_BODY = "Js.FileBody";

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                int cacheTime = 300;
                string file = context.Request.PhysicalPath;
                if (!File.Exists(file))
                    return;

                string body = string.Empty;

                if (context.Cache[SCRIPT_CACHE_BODY + file] != null)
                    body = context.Cache[SCRIPT_CACHE_BODY + file].ToString();

                if (body == string.Empty)
                {
                    using (StreamReader reader = new StreamReader(file))
                    {

                        StringBuilder sb = new StringBuilder();
                        while (reader.Peek() >= 0)
                        {
                            body = reader.ReadLine();
                            body = body.Trim();
                            if (body.StartsWith("//"))
                                body = string.Empty;

                            if (body.Length > 0)
                                sb.Append(body + Environment.NewLine);
                        }

                        body = sb.ToString();
                    }

                    body = StripComments(body);
                   
                    body = Regex.Replace(body, @"^[\s]+|[ \f\r\t\v]+$", String.Empty);
                    body = Regex.Replace(body, @"([+-])\n\1", "$1 $1");
                    body = Regex.Replace(body, @"([^+-][+-])\n", "$1");
                    body = Regex.Replace(body, @"([^+]) ?(\+)", "$1$2");
                    body = Regex.Replace(body, @"(\+) ?([^+])", "$1$2");
                    body = Regex.Replace(body, @"([^-]) ?(\-)", "$1$2");
                    body = Regex.Replace(body, @"(\-) ?([^-])", "$1$2");
                    body = Regex.Replace(body, @"\n([{}()[\],<>/*%&|^!~?:=.;+-])", "$1");
                    body = Regex.Replace(body, @"(\W(if|while|for)\([^{]*?\))\n", "$1");
                    body = Regex.Replace(body, @"(\W(if|while|for)\([^{]*?\))((if|while|for)\([^{]*?\))\n", "$1$3");
                    body = Regex.Replace(body, @"([;}]else)\n", "$1 ");
                    body = Regex.Replace(body, @"(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,}(?=&nbsp;)|(?<=&ndsp;)\s{2,}(?=[<])", String.Empty);

                    CacheDependency cd = new CacheDependency(file);
            
                    context.Cache.Insert(SCRIPT_CACHE_BODY + file, body, null, DateTime.Now.AddYears(cacheTime), TimeSpan.Zero);
                }

                context.Response.Write(body);
            }
            catch (Exception ex)
            {
                context.Response.Write(ex.Message);
            }
        }

        private string StripComments(string body)
        {
            return Regex.Replace(body, @"/\*.+?\*/", "", RegexOptions.Singleline);
            // Regex reg = new Regex(@"(?<=[^])\t{2,}|(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,11}(?=[<])|(?=[\n])\s{2,}");
            // body= reg.Replace(body, string.Empty);
            // return body;
        }

        #endregion
    }
}